﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace nr.GLV.Windows.Controls
{
    public partial class SettingsManager : Component
    {
        private string fileName;
        public string FileName
        {
            get { return fileName; }
            set
            {
                fileName = value;
                Load();
            }
        }

        public string FullFileName
        {
            get
            {
                string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

                return System.IO.Path.Combine(path, FileName);
            }
        }

        private static Dictionary<string, string> Properties { get; set; }

        public string this[string key]
        {
            get
            {
                if (Properties.ContainsKey(key))
                    return Properties[key];
                else
                    return string.Empty;
            }
            set
            {
                if (value.Length == 0)
                {
                    if (Properties.ContainsKey(key)) Properties.Remove(key);
                }
                else
                    Properties[key] = value;
            }
        }

        private void Load()
        {
            string settingsFileName = FullFileName;
            if (System.IO.File.Exists(settingsFileName))
                try
                {
                    Properties.Clear();
                    XDocument document = XDocument.Load(settingsFileName);
                    XNamespace ns = "http://nellorizzo.altervista.org/glv/properties";
                    XName nameAttr = ns.GetName("name");
                    XName valueAttr = ns.GetName("value");
                    XElement properties = document.Root.Element(ns.GetName("properties"));
                    foreach (XElement element in properties.Elements())
                        Properties.Add(element.Attribute(nameAttr).Value, element.Attribute(valueAttr).Value);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.Print(ex.ToString());
                    System.IO.File.Delete(settingsFileName);
                }
        }

        public void Save()
        {
            string settingsFileName = FullFileName;
            XDocument document = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
            XNamespace ns = "http://nellorizzo.altervista.org/glv/properties";
            XElement root = new XElement(ns.GetName("settings"));
            XElement properties = new XElement(ns.GetName("properties"));
            root.Add(properties);
            document.AddFirst(root);
            XName nameAttr = ns.GetName("name");
            XName valueAttr = ns.GetName("value");

            foreach (string key in Properties.Keys)
            {
                XElement node = new XElement(ns.GetName("property"));
                node.Add(new XAttribute(nameAttr, key), new XAttribute(valueAttr, Properties[key]));
                properties.Add(node);
            }
            try
            {
                document.Save(settingsFileName);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.Print(ex.ToString());
                try { System.IO.File.Delete(settingsFileName); }
                finally { }
            }
        }

        static SettingsManager()
        {
            Properties = new Dictionary<string, string>();
        }

        public SettingsManager()
        {
            ResetFields();

            InitializeComponent();
        }

        private void ResetFields()
        {
            FileName = string.Format("{0}.{1}.settings", System.Windows.Forms.Application.ProductName, System.Windows.Forms.Application.ProductVersion);
        }

        public SettingsManager(IContainer container)
        {
            ResetFields();

            container.Add(this);
            InitializeComponent();
        }
    }
    public delegate void SettingsLoadEventHandler(object sender, EventArgs e);
    public delegate void SettingsSavedEventHandler(object sender, EventArgs e);

    public class SettingsFileFailureException : Exception
    {
        public SettingsFileFailureException() : base() { }
        public SettingsFileFailureException(string message) : base(message) { }
        public SettingsFileFailureException(string message, Exception innerException) : base(message, innerException) { }
    }

}
